#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/module.h>
#include <linux/init.h>

#define LED_NAME "gpioled_red"

static int red_gpio = -1;
struct led_classdev red_led;

static void red_led_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness)
{
    gpio_set_value(red_gpio, brightness);
}

static int __init my_red_led_init(void)
{
    struct device_node *np;
    int ret;

    // 使用NULL而不是"NULL"获取设备树节点
    np = of_find_node_by_name(NULL, "red");
    if (!np) {
        pr_err("Failed to find red LED device tree node\n");
        return -ENODEV;
    }

    red_gpio = of_get_named_gpio(np, "gpios", 0);
    of_node_put(np);
    if(red_gpio < 0) {
        pr_err("Failed to get GPIO for red LED\n");
        return -ENODEV;
    }

    ret = gpio_request(red_gpio, LED_NAME);
    if(ret) {
        pr_err("gpio_request failed for red LED\n");
        return ret;
    }

    ret = gpio_direction_output(red_gpio, 0); // 初始状态关闭红色LED
    if(ret) 
    {
        pr_err("gpio_direction_output failed for red LED\n");
        gpio_free(red_gpio);
        return ret;
    }

    // 初始化并注册红色LED
    red_led.name = LED_NAME;
    red_led.brightness_set = red_led_brightness_set;
    red_led.brightness = LED_OFF;

    ret = led_classdev_register(NULL, &red_led);
    if (ret) {
        pr_err("led_classdev_register failed for red LED\n");
        gpio_free(red_gpio);
        return ret;
    }
    printk("Red LED module is loaded\n");
    return 0;
}

static void __exit my_red_led_exit(void)
{
    led_classdev_unregister(&red_led);
    gpio_free(red_gpio);
    printk(KERN_EMERG  "Red LED module is unloaded\n");
}

module_init(my_red_led_init);
module_exit(my_red_led_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("JiaYi");
MODULE_DESCRIPTION("Red LED driver using LED subsystem");